package io.finer.erp.jeecg.jolimark.print;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.finer.erp.jeecg.jolimark.comm.Config;
import io.finer.erp.jeecg.jolimark.comm.HttpClientUtil;
import io.finer.erp.jeecg.jolimark.enums.PrinterEnum;
import io.finer.erp.jeecg.jolimark.factory.*;
import io.finer.erp.jeecg.jolimark.model.PrintFileRequestModel;
import io.finer.erp.jeecg.jolimark.model.PrintRequestModel;

import java.util.List;

/**
 * 基础打印类
 * 
 * @author Jolimark
 *
 */
public abstract class AbstractPrint {
	/**
	 * 打印方法
	 * 
	 * @param printMethod 打印方法名
	 * @param model       打印请求参数
	 */
	protected void print(String printMethod, PrintRequestModel model) {
		boolean validationResult = requestValidation(printMethod, model);
		if (!validationResult) {
			return;
		}

		if (!billContentValidation(model.getBillContent())) {
			return;
		}

		String params = convert(model);
		String urlString = getUrl() + printMethod;

		String responseString = HttpClientUtil.sendHttpPost(urlString, params);
		JSONObject responseJson = JSON.parseObject(responseString);
		Out(printMethod + ":" + urlString);
		Out(printMethod + ":" + params);

		Out(responseString);
		Out("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");

		if(responseJson.getInteger("return_code").equals(10103)||responseJson.getInteger("return_code").equals(10102)){
			CreateAccessToken createAccessToken = new CreateAccessToken();
			createAccessToken.accessToken();
			model.setAccessToken(Config.getAccessToken());
			print(printMethod,model);
		}
	}

	/**
	 * 获取HTML URL
	 * 
	 * @return URL
	 */
	protected String getUrl() {
		return Config.getUrlV3();
	}

	/**
	 * 打印内容参数校验
	 * 
	 * @param billContent 打印内容
	 * @return
	 */
	protected boolean billContentValidation(String billContent) {
		if (billContent == null || billContent.trim().isEmpty()) {
			Out("错误：billContent 不可空");
			return false;
		}

		return true;
	}

	/**
	 * 打印纸张参数校验
	 * 
	 * @param model
	 * @return
	 */
	protected boolean paperValidation(PrintRequestModel model) {
		if (model.getPaperHeight() <= 0) {
			Out("错误：paperHeight 不能小于0");
			return false;
		}

		return true;
	}

	/**
	 * 参数校验
	 * 
	 * @param printMethod 打印方法
	 * @param model       打印请求参数
	 * @return True or False
	 */
	private boolean requestValidation(String printMethod, PrintRequestModel model) {
		Out(printMethod + " request validation");

		if (model == null) {
			Out("错误：PrintRequestModel 未将对象引用到实例");
			return false;
		}

		if (model.getAppId() == null || model.getAppId().trim().isEmpty()) {
			Out("错误：appId 不可空");
			return false;
		}

		if (model.getAccessToken() == null || model.getAccessToken().trim().isEmpty()) {
			Out("错误：accessToken 不可空");
			return false;
		}

		if (model.getDeviceIds() == null || model.getDeviceIds().isEmpty()) {
			Out("错误：deviceIds 不可空");
			return false;
		}

		if (model.getCusOrderId() == null || model.getCusOrderId().trim().isEmpty()) {
			Out("错误：cusOrderId 不可空");
			return false;
		}

		if (model.getCopies() <= 0) {
			Out("错误：copies 不能小于0");
			return false;
		}

		if (model.getTimeout() <= 0) {
			Out("错误：timeout 不能小于0");
			return false;
		}

		if (model.getDeviceIds().size() > 100) {
			Out("错误：deviceIds 不能超过100");
			return false;
		}

		return true;
	}

	/**
	 * 信息输出
	 * 
	 * @param messageString 消息
	 */
	public void Out(String messageString) {
		System.out.println(messageString);
	}

	/**
	 * 将打印参数对象转成字符串形式键值对
	 * 
	 * @param model 打印请求参数
	 * @return 字符串键值对
	 */
	protected String convert(PrintRequestModel model) {
		StringBuilder result = new StringBuilder();
		result.append("app_id=").append(model.getAppId());
		result.append("&access_token=").append(model.getAccessToken());
		result.append("&device_ids=").append(buildDeviceIds(model.getDeviceIds()));
		result.append("&copies=").append(model.getCopies());
		result.append("&cus_orderid=").append(model.getCusOrderId());

		if (model.getBillContent() != null && !model.getBillContent().isEmpty())
			result.append("&bill_content=").append(model.getBillContent());
		if (model.getPaperHeight() > 0)
			result.append("&paper_height=").append(model.getPaperHeight());
		if (model.getPaperType() != null)
			result.append("&paper_type=").append(model.getPaperType().getPaperType());
		if (model.getPaperWidth() > 0)
			result.append("&paper_width=").append(model.getPaperWidth());
		if (model.getTimeout() > 0)
			result.append("&time_out=").append(model.getTimeout());

		return result.toString();
	}

	/**
	 * 将字符串的集合转化成字符串集，以逗号分隔
	 * 
	 * @param ids 字符串集
	 * @return 以逗号分隔的字符集
	 */
	private String buildDeviceIds(List<String> ids) {
		if (ids == null || ids.isEmpty())
			return "";

		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < ids.size(); i++) {
			String item = ids.get(i);
			stringBuilder.append(item);
			if (i + 1 < ids.size())
				stringBuilder.append(",");
		}
		return stringBuilder.toString();
	}

	/**
	 * 根据打印机类型构建一组默认的打印请求参数
	 * 
	 * @param printerEnum 打印机类型
	 * @return 打印请求参数
	 */
	protected PrintRequestModel buildRequest(PrinterEnum printerEnum) {
		IPrinterFactory factory = buildFactory(printerEnum);
		return factory.createPrintRequest();
	}

	private IPrinterFactory buildFactory(PrinterEnum printerEnum) {
		switch (printerEnum.getType()) {
		case 1:
			return new MCPFactory(printerEnum);
		case 2:
			return new CFPFactory(printerEnum);
		case 3:
			return new CLPFactory(printerEnum);
		case 4:
			return new CLQFactory(printerEnum);
		default:
			break;
		}

		return null;
	}
}